<?php

// require_once '../vendor/autoload.php';

namespace Framework;

use App\Controllers\ErrorController;
use Framework\Middleware\Authorise;


// $uri = $_SERVER['REQUEST_URI'];

// $uri = str_replace(basePath(),'',$uri);

// $uri = trim($uri,'/');

// if ($uri === '') {
//     # code...
//     $uri = 'home';
// }

// $routes = require basePath('routes.php');

// if (array_key_exists($uri, $routes)) {
//     # code...
//     require(basePath($routes[$uri]));
// } else {
//     # code...
//     http_response_code(404);
//     require(basePath($routes['404']));
// }

class Router{
    protected $routes = [];

    private function registerRoute($method,$uri,$action,$middleware = []){

        // $arr = explode('@',$action);
        // inspectAndDie($arr);
        list($controller, $controllerMethod) = explode('@',$action);
        // inspectAndDie($controllerMethod);

        $this -> routes[] = [
            'method' => $method,
            'uri' => $uri,
            'controller' => $controller,
            'controllerMethod' => $controllerMethod,
            'middleware' => $middleware
        ];
    }

    public function addGet($uri,$controller,$middleware = []){
        $this -> registerRoute('GET',$uri,$controller,$middleware);
    }

    public function addPost($uri,$controller,$middleware = []){
        $this -> registerRoute('POST',$uri,$controller,$middleware);
    }

    public function addPut($uri,$controller,$middleware = [])
    {
        # code...
        $this -> registerRoute('PUT',$uri,$controller,$middleware);
    }

    public function addDelete($uri,$controller,$middleware = [])
    {
        # code...
        $this -> registerRoute('DELETE',$uri,$controller,$middleware);
    }

    public function route($uri){

        $requestMethod = $_SERVER['REQUEST_METHOD'];

        if ($requestMethod === 'POST' && isset($_POST['_method'])) {
            # code...
            $requestMethod = strtoupper($_POST['_method']);
        }

        $uriSegments = explode('/', trim($uri, '/'));

        foreach ($this -> routes as $route) {

            $routeSegments = explode('/', trim($route['uri'], '/'));

            $match = false;

            # code...
            // if ($route['uri'] === $uri && $route['method'] === $method) {
            if (count($uriSegments) === count($routeSegments) && strtoupper($route['method'] === $requestMethod)) {
                $params = [];

                $match = true;

                for ($i=0; $i < count($uriSegments); $i++) { 
                    # code...
                    if ($routeSegments[$i] !== $uriSegments[$i] && !preg_match('/\{(.+?)\}/', $routeSegments[$i])) {
                        # code...
                        $match = false;
                        break;
                    }

                    if (preg_match('/\{(.+?)\}/', $routeSegments[$i], $matches)) {
                        # code...
                        $params[$matches[1]] = $uriSegments[$i];
                    }
                }
                
                # code...
                // require basePath('App/' . $route['controller']);
                // return;

                // $controller = 'App\\Controllers\\' . $route['controller'];
                // $controllerMethod = $route['controllerMethod'];

                // $controllerInstance = new $controller();
                // $controllerInstance->$controllerMethod();
            }

            if ($match) {
                # code...

                foreach($route['middleware'] as $middleware){
                    (new Authorise())->handle($middleware);
                }
                
                $controller = 'App\\Controllers\\' . $route['controller'];
                // echo $controller;
                $controllerMethod = $route['controllerMethod'];

                $controllerInstance = new $controller();
                $controllerInstance->$controllerMethod($params);
                return;
            }
        }

        // http_response_code(404);
        // loadView('error/404');
        // $this->error();  // 默认传递404

        ErrorController::notFound();
    }

    public function error($httpCode = 404)
    {
        http_response_code($httpCode);
        loadView("error/{$httpCode}");
        exit;
    }
}
